<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta name="generator" content="HTML Tidy for Linux/x86 (vers 1st November 2003), see www.w3.org"/>
    <title>JavaScript: Basics</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="copyright" content="Copyright &#169; 2005-2010 W3C (MIT, ERCIM, Keio)"/>
    <meta name="duration" content="5"/>
    <meta name="font-size-adjustment" content="-2"/>

    <link rel="stylesheet" href="styles/slidy.css" type="text/css"/>
    <link rel="stylesheet" href="styles/w3c-blue.css" type="text/css"/>
	<script type="text/javascript" src="scripts/slidy.js" charset="utf-8">//</script>

    <link type="text/css" rel="stylesheet" href="styles/shCoreDefault.css"/>
    <script type="text/javascript" src="scripts/shCore.js"></script>
    <script type="text/javascript" src="scripts/shBrushJScript.js"></script>
    <script type="text/javascript" src="scripts/shBrushJava.js"></script>

    <link type="text/css" rel="stylesheet" href="styles/presentation.css"/>
    <script type="text/javascript" src="scripts/presentation.js"></script>
</head>


<body>
<div class="background">
    <img alt="" id="head-icon" src="graphics/icon-blue.png"/>
</div>

<div class="background slanty">
</div>

<div class="slide cover title">
    <img class="hidden" src="graphics/bullet.png" alt=""/>
    <img class="hidden" src="graphics/fold.gif" alt=""/>
    <img class="hidden" src="graphics/unfold.gif" alt=""/>
    <img class="hidden" src="graphics/fold-dim.gif" alt=""/>
    <img class="hidden" src="graphics/nofold-dim.gif" alt=""/>
    <img class="hidden" src="graphics/unfold-dim.gif" alt=""/>
    <img class="hidden" src="graphics/bullet-fold.gif" alt=""/>
    <img class="hidden" src="graphics/bullet-unfold.gif" alt=""/>
    <img class="hidden" src="graphics/bullet-fold-dim.gif" alt=""/>
    <img class="hidden" src="graphics/bullet-nofold-dim.gif" alt=""/>
    <img class="hidden" src="graphics/bullet-unfold-dim.gif" alt=""/>

    <h1>Browser</h1>

    <div style="position: absolute; bottom: 20px;">
        <p>Alex Kolonitsky (Java)</p>
        <p><a href="http://javascript-learning-courses.googlecode.com/svn/trunk/Intermidiate-04-OOP.html">http://javascript-learning-courses.googlecode.com/svn/trunk/Intermidiate-04-OOP.html</a></p>
    </div>
</div>

<div class="slide">
    <h1>HTML DOM</h1>

    <ul>
        <li>Events</li>
        <li>Walking on tree</li>
        <li>Performance Tips</li>
    </ul>
</div>

<div class="slide">
    <h1>HTML DOM</h1>

    <ul class="content">
        <li class="current">Events</li>
        <li>Walking on tree</li>
        <li>Performance Tips</li>
    </ul>
</div>

<div class="slide">
    <h1>Events</h1>

    <ul>
        <li>Назначение обработчиков</li>
        <li>Event Object</li>
        <li>Порядок срабатывания событий</li>
        <li>Действие браузера по умолчанию</li>
    </ul>
</div>

<div class="slide">
    <h1>Events</h1>

    <ul class="content">
        <li class="current">Назначение обработчиков</li>
        <li>Event Object</li>
        <li>Порядок срабатывания событий</li>
        <li>Действие браузера по умолчанию</li>
    </ul>
</div>

<div class="slide">
    <h1>Назначение обработчиков</h1>

    <ul>
        <li>Через атрибут HTML-тега</li>
        <li>Через свойство объекта</li>
        <li>Специальные методы</li>
        <li>Через фрэймворк</li>
    </ul>
</div>

<div class="slide">
    <h1>Через атрибут HTML-тега</h1>

    <pre class="brush: js">
        &lt;input id="b1" value="Нажми Меня"
            onclick="alert('Спасибо!');" type="button"/>
    </pre>
    <p>или так:</p>
    <pre class="brush: js">
        &lt;script type="text/javascript">
            function hello() {
                alert('Спасибо!');
            }
        &lt;/script>
        &lt;input type="button" onclick="hello()"
            value="Считать кролей!"/>
    </pre>
</div>

<div class="slide">
    <h1>Через свойство объекта</h1>

    <pre class="brush: js">
        &lt;input id="myElement" type="button"
            value="Нажми меня"/>

        document.getElementById('myElement').onclick
            = function() { alert('Спасибо') };
        
        function doSomething() {
            alert('Спасибо')
        };
        
        document.getElementById('button').onclick
            = doSomething;
    </pre>
</div>

<div class="slide">
    <h1>Специальные методы</h1>

    <ul>
        <li>
            <pre class="brush: js">
                element.addEventListener(имяCобытия,
                    обработчик, фаза)
                element.removeEventListener(имяCобытия,
                    обработчик, фаза)
            </pre>
        </li>
        <li>
            <p>IE особенный:</p>
            <pre class="brush: js">
                element.attachEvent( "on"+имя события,
                    обработчик)
                element.detachEvent( "on"+имя события,
                    обработчик)
            </pre>
        </li>
    </ul>
</div>

<div class="slide">
    <h1>Через фрэймворк</h1>

    <pre class="brush: js">
        // mootools
        element.addEvent(имяCобытия, обработчик);

        // jQuery
        $('#foo').bind('click', function() {
            alert('User clicked on "foo."');
        });
    </pre>
</div>

<div class="slide">
    <h1>Назначение обработчиков: End</h1>

    <ul>
        <li>Через атрибут HTML-тега</li>
        <li>Через свойство объекта</li>
        <li>Специальные методы</li>
        <li>Через фрэймворк</li>
    </ul>
</div>

<div class="slide">
    <h1>Events</h1>

    <ul class="content">
        <li class="done">Назначение обработчиков</li>
        <li class="current">Event Object</li>
        <li>Порядок срабатывания событий</li>
        <li>Действие браузера по умолчанию</li>
    </ul>
</div>

<div class="slide">
    <h1>Event Object</h1>

    <p>Объект событие всегда передается обработчику и содержит массу полезной информации о том где и какое событие произошло.</p>

    <pre class="brush: js">
        function doSomething(event) {
            event = event || window.event

            // Теперь event - объект события во всех браузерах.
        }

        element.onclick = doSomething
    </pre>
</div>

<div class="slide">
    <h1>Events</h1>

    <ul>
        <li class="done">Назначение обработчиков</li>
        <li class="done">Event Object</li>
        <li class="current">Порядок срабатывания событий</li>
        <li>Действие браузера по умолчанию</li>
    </ul>
</div>

<div class="slide">
    <h1>Порядок срабатывания событий</h1>

    <img src="graphics/Events/event-order-bubbling.gif" alt="" style="float: right; margin: 1em;">
    <dl>
        <dt>Bubbling</dt>
        <dd>Такой порядок называется "всплывающим", потому что событие поднимается с самых "глубоких" элементов в представлении DOM, к самым "верхним", как пузырек воздуха в воде.</dd>
    </dl>
</div>

<div class="slide">
    <h1>Порядок срабатывания событий</h1>

    <img src="graphics/Events/event-order-capturing.gif" alt="" style="float: right; margin: 1em;">
    <dl>
        <dt>Capturing</dt>
        <dd>В этой модели сначала будет выполнен обработчик на элементе 1, затем - на элементе 2 и последним будет выполнен обработчик на элементе 3. Она называется "перехват", потому что родительские элементы могут обработать событие раньше, чем непосредственная цель события, как бы "перехватывая" обработку.</dd>
    </dl>
</div>

<div class="slide">
    <h1>Порядок срабатывания событий</h1>

    <table>
        <tr>
            <td>Bubbling</td>
            <td>Capturing</td>
        </tr>
        <tr>
            <td>
                <div class="d1" onclick="highlightMe(this)">d1
                    <div class="d2" onclick="highlightMe(this)">d2
                        <div class="d3" onclick="highlightMe(this)">d3</div>
                    </div>
                </div>
            </td>
            <td>
                <div id="capt1" class="d1">d1
                    <div id="capt2" class="d2">d2
                        <div id="capt3" class="d3">d3</div>
                    </div>
                </div>

                <script type="text/javascript">
                    function highlightMe(elem) {
                        elem.style.backgroundColor = 'yellow';
                        alert(elem.className);
                        elem.style.backgroundColor = ''
                    }

                    function highlightMe2(e) {
                        highlightMe(e.currentTarget);
                    }

                    document.getElementById("capt1").addEventListener("click", highlightMe2, true);
                    document.getElementById("capt2").addEventListener("click", highlightMe2, true);
                    document.getElementById("capt3").addEventListener("click", highlightMe2, true);
                </script>
            </td>
        </tr>
    </table>
</div>

<div class="slide">
    <h1>Порядок обработки в стандарте W3C</h1>

    <img src="graphics/Events/event-order-w3c.gif" alt=""  style="float: right; margin: 1em;"/>
    <p>При совершении действия, сначала событие перехватывается, пока не достигнет конечного элемента, затем всплывает.</p>
</div>

<div class="slide">
    <h1>Events</h1>

    <ul class="content">
        <li class="done">Назначение обработчиков</li>
        <li class="done">Event Object</li>
        <li class="done">Порядок срабатывания событий</li>
        <li class="current">Действие браузера по умолчанию</li>
    </ul>
</div>

<div class="slide">
    <h1>Действие браузера по умолчанию</h1>

    <p>Браузер имеет своё собственное поведение по умолчанию для различных событий (клик по ссылке).</p>

    <pre class="brush: js">
        element.onclick = function(event) {
            event = event || window.event

            if (event.preventDefault) {
                // Вариант стандарта W3C:
                event.preventDefault()
            } else {
                // Вариант Internet Explorer:
                event.returnValue = false
            }
        }
    </pre>
</div>

<div class="slide">
    <h1>Другое</h1>

    <ul>
        <li>В JS всего один поток выполнения.</li>
        <li>
            <pre class="brush: js">
                function handler(e) {
                  e.preventDefault() // браузер - стоять
                  e.stopPropagation() // событие - не всплывать
                  return false // и вообще, мне больше ничего не надо
                }
            </pre>
        </li>
    </ul>
</div>

<div class="slide">
    <h1>Ссылки</h1>

    <ul>
        <li><a href="http://javascript.ru/tutorial/events/intro">Введение в события</a></li>
        <li><a href="http://javascript.ru/tutorial/events">События</a></li>
        <li><a href="https://developer.mozilla.org/en/DOM/DOM_event_reference">DOM event reference</a></li>
        <li><a href="http://www.w3.org/TR/DOM-Level-3-Events/">Document Object Model (DOM) Level 3 Events Specification</a></li>
        <li><a href="http://habrahabr.ru/blogs/javascript/126471/">Events bubbling и events capturing</a></li>
    </ul>

</div>

<div class="slide">
    <h1>Поиск в DOM дереве</h1>

    <p>Хочется обратить внимание на многообразие возможностей.</p>
    <ul>
        <li>getElementBy…</li>
        <li>XPath</li>
        <li>TreeWalker</li>
        <li>The DOM tree</li>
        <li>Frameworks</li>
    </ul>
</div>

<div class="slide">
    <h1>getElementBy…</h1>

    <ul>
        <li>getElementsByTagName</li>
        <li>getElementsByClassName</li>
        <li>getElementById</li>
        <li>querySelectorAll</li>
    </ul>

    <pre class="brush: js">
        document.querySelectorAll(".slide")[23].getElementsByTagName("ul");
    </pre>
</div>

<div class="slide">
    <h1>XPath</h1>

    <pre class="brush: js">
        document.evaluate("//*[@title]", document,
            null, XPathResult.ANY_TYPE, null);
    </pre>
</div>

<div class="slide">
    <h1>The DOM tree</h1>

    <pre class="brush: js">
        x.parentNode.firstChild.nextSibling.children[2]
    </pre>
    <ul>
        <li>childNodes[]</li>
        <li>children[]</li>
        <li>first/last Child</li>
        <li>nextSibling</li>
        <li>parentNode</li>
        <li>previousSibling</li>
    </ul>
</div>

<div class="slide">
    <h1>TreeWalker</h1>

    <div>
        <pre class="brush: java">
            processMe(TreeWalker tw) {
                Node n = tw.getCurrentNode();
                nodeStartActions(tw);
                for (Node child=tw.firstChild();
                    child != null; child=tw.nextSibling()) {
            
                    processMe(tw);
                }

                tw.setCurrentNode(n);
                nodeEndActions(tw);
            }
        </pre>
    </div>
</div>

<div class="slide">
    <h1>TreeWalker</h1>

    <table style="font-size: 50%">
        <tr>
            <td>
                <pre class="brush: java">
                    processMe(TreeWalker tw) {
                        Node n = tw.getCurrentNode();
                        nodeStartActions(tw);
                        for (Node child=tw.firstChild();
                            child != null; child=tw.nextSibling()) {
                    
                            processMe(tw);
                        }

                        tw.setCurrentNode(n);
                        nodeEndActions(tw);
                    }
                </pre>
            </td>
            <td>
                <pre class="brush: java">
                    processMe(Node n) {
                        nodeStartActions(n);
                        for (Node child=n.firstChild();
                             child != null; child=child.nextSibling()) {
                    
                            processMe(child);
                        }
                       nodeEndActions(n);
                    }
                </pre>
            </td>
        </tr>
    </table>
</div>

<div class="slide">
    <h1>TreeWalker</h1>

    <p>The advantage of using a TreeWalker instead of direct Node navigation is that the TreeWalker allows the user to choose an appropriate view of the tree. Flags may be used to show or hide Comments or ProcessingInstructions; entities may be expanded or shown as EntityReference nodes. In addition, NodeFilters may be used to present a custom view of the tree.</p>
</div>

<div class="slide">
    <h1>Frameworks</h1>

    <pre class="brush: js">
        // jQuery
        $("#foo .bar")

        // Mootools
        $$("#foo .bar")
    </pre>
</div>

<div class="slide">
    <h1>Links</h1>

    <ul>
        <li><a href="http://www.w3.org/TR/selectors/">Selectors Level 3</a></li>
        <li><a href="http://www.w3.org/TR/DOM-Level-3-XPath/">DOM Level 3 XPath Specification</a></li>
        <li><a href="http://www.nczonline.net/blog/2009/03/17/xpath-in-javascript-part-1/">XPath in JavaScript, Part 1</a></li>
        <li><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/traversal.html">Document Object Model Traversal</a></li>
        <li><a href="http://www.ibm.com/developerworks/xml/library/x-tiptreewlk/index.html">Tip: Traversing an XML document with a TreeWalker</a></li>
    </ul>
</div>

<div class="slide">
    <h1>Performance Tips</h1>

    <ul>
        <li>DOM</li>
        <li>Modify DOM</li>
        <li>Modify Styles</li>
        <li>Cache</li>
        <li>JavaScript</li>
    </ul>
</div>

<div class="slide">
    <h1>Performance Tips</h1>

    <ul class="content">
        <li class="current">DOM</li>
        <li class="current">Modify DOM</li>
        <li class="current">Modify Styles</li>
        <li>Cache</li>
        <li>JavaScript</li>
    </ul>
</div>

<div class="slide">
    <h1>Repaint and Reflow</h1>

    <img src="graphics/Performance/render.png" alt="">
</div>

<div class="slide">
    <h1>Repaint</h1>

    <p>перерисовка страницы, происходить каждый раз когда меняется визуальное представление страницы. Это может быть выделение чего-то в рамку или изменение фона элемента, в таком случае будут пересованы и все внутренние элементы.</p>
</div>

<div class="slide">
    <h1>Reflow</h1>

    <p>более трудоемкая операция, возникает каждый раз когда происходит манипуляции с DOM деревом, применения стилей или ещё чего-нибудь что может повлиять на расположение элементов на странице. Это требует полного пересчета всех позиций внутренних и во многих случаях внешних элементов.</p>
</div>

<div class="slide">
    <h1>Modify DOM</h1>

    <ul>
        <li>Делать несколько изменений за один раз. В случае создания DOM фрагмента это значит, что мы полностью создаем элемент со всем контентом и только после этого добавляем его в дерево.</li>
    </ul>
</div>

<div class="slide">
    <h1>Modify DOM</h1>

    <ul>
        <li>
            Производить изменения над копией элемента, после чего заменять оригинал измененной копией
            <pre class="brush: js">
                var objCopy = obj.clone();
                ... work with objCopy ...
                obj.getParent().replace(obj, objCopy);
            </pre>
        </li>
        <li>Делать изменения над невидимыми элементами  (display: none)</li>
    </ul>
</div>

<div class="slide">
    <h1>Modify Styles</h1>

    <p>Аналогичное изменению DOM</p>
    <ul>
        <li>все (составные) изменения стилей выносить в css классы. Так, например, для подсветки элемента вы писали:
            <pre class="brush: js">
                elem.style.background = ‘white’
                elem.style.color = ‘black’
                elem.style.border = ‘1px solid red’
            </pre>
        </li>
    </ul>
</div>

<div class="slide">
    <h1>Modify Styles</h1>

    <ul>
        <li>теперь
            <pre class="brush: js">
                highlight {
                    background: white;
                    color: black;
                    border: 1px solid red;
                }

                elem.className = ‘highlight’;
            </pre>
        </li>
        <li>Вы также можете установить свойство style.cssText (или setAttribute(‘style’, …)) элемента, просто собрав в строку все нужные стили</li>
    </ul>
</div>


<div class="slide">
    <h1>Performance Tips</h1>

    <ul class="content">
        <li class="done">DOM</li>
        <li class="done">Modify DOM</li>
        <li class="done">Modify Styles</li>
        <li class="current">Cache</li>
        <li>JavaScript</li>
    </ul>
</div>

<div class="slide">
    <h1>Cache</h1>

    <p>Не кэшируются, полученные ‘тяжелыми мучениями’, значения</p>
    <pre class="brush: js">
        if (document.getElementById(‘id’).attr1) {
            document.getElementById(‘id’).attr2 = val2;
            document.getElementById(‘id’).attr3 = val3;
        }

        // или
        if ($(‘id’).attr1 && ($(‘id’).attr2 = val2)) {
            $('id').attr3 = val3;
        }
    </pre>
</div>

<div class="slide">
    <h1>Cache</h1>

    <p>$(‘…’) это поиск по дереву документа и хорошо бы кэшировать результат этого поиска в локальной переменной</p>
    <pre class="brush: js">
        var el = $(‘id’);
        if (el.attr1) {
            el.attr2 = val2;
            el.attr3 = val3;
        }
    </pre>
</div>

<div class="slide">
    <h1>Performance Tips</h1>

    <ul class="content">
        <li class="done">DOM</li>
        <li class="done">Modify DOM</li>
        <li class="done">Modify Styles</li>
        <li class="done">Cache</li>
        <li class="current">JavaScript</li>
    </ul>
</div>

<div class="slide">
    <h1>JavaScript</h1>

    <ul>
        <li>Eval</li>
        <li>Loops</li>
        <li>String</li>
        <li>RegExp</li>
    </ul>
</div>

<div class="slide">
    <h1>JavaScript: Eval</h1>

    <p>Никогда не используйте.</p>
</div>

<div class="slide">
    <h1>JavaScript: Loops</h1>

    <ul>
        <li>for-in</li>
        <li>length</li>
        <li>Extract static calculations</li>
    </ul>

    <p>
        <a href="http://dev.by/blog/32099">Заметки об оптимизации программ. Часть 1: о пользе Loop-invariant Code Motion</a>
    </p>
</div>

<div class="slide">
    <h1>JavaScript: String</h1>

    <pre class="brush: js">
        var res = “Hello, ” + herName + “, my name ”
                    + myName + “!!!”;
    </pre>

    <p>заменяем на </p>
    <pre class="brush: js">
        var res = [“Hello, ”, herName, “, my name ”,
                    myName, “!!!”].join(‘’);

        // или
        var res = "Hello, ";
        res += herName;
        res += ", my name";
    </pre>
</div>

<div class="slide">
    <h1>Нужно кэшировать</h1>

    <ul>
        <li>this.options.countrySelector.widget</li>
        <li>RegExp</li>
        <li>With</li>
        <li>try…catch</li>
    </ul>
</div>

<div class="slide">
    <h1>Links</h1>

    <ul>
        <li><a href="http://dev.opera.com/articles/view/efficient-javascript/">Efficient JavaScript</a></li>
        <li><a href="http://www.slideshare.net/madrobby/extreme-javascript-performance">Хорошая презентация</a></li>
        <li><a href="http://jsperf.com/">Место, где удобней всего проводить тесты производительности</a></li>
    </ul>
</div>

<div class="slide">
    <h1>setTimeout/setInterval</h1>
</div>

<div class="slide">
    <h1>Вопросы / Предложения</h1>

    <ul>
        <li>Alex.Kolonitsky@gmail.com</li>
        <li>akolonitsky@exadel.com</li>
        <li>Skype: Desargues_</li>
        <li>http://code.google.com/p/javascript-learning-courses/issues/list</li>
    </ul>
</div>
</body>
</html>
